package chapter08;

import javax.swing.*;
import java.awt.*;
import java.util.Date;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.function.Supplier;

/**
 * @Author: insight
 * @Description: 泛型中的强制类型转换
 * @LastDate: 2020/11/27
 */
public class Test05_GenericAndJVM {

    public static void main(String[] args) {
    }

    /**
     * 调用遗留代码
     */
    public static void callLegacyCode() {
        var slider = new JSlider();
        Dictionary<Integer, Component> table = new Hashtable<>();
        table.put(0, new JLabel(new ImageIcon("")));
        /*
          setLabelTable( Dictionary labels )
          输入Dictionary已经是泛型类
          但是JSlider的setLabelTable的参数并没有更新
          此处是已知类型赋给Object
         */
        slider.setLabelTable(table);
        /*
         * 另外一个相反的情形
         * 原始类型Object赋给一个使用泛型的变量
         * 此时会警告
         */
        Dictionary<Integer, Component> table2 = slider.getLabelTable();
    }

    /**
     * 泛型语句的类型转换
     */
    public static void typeConversionOfStatement() {
        var pair = new Pair<Integer>();
        pair.setFirst(1);
        var firstWithType = pair.<Integer>getFirst();
        /*
         * 以下这句会变成两条指令
         * 调用方法
         * 强制类型转换
         */
        var firstWithoutType = pair.getFirst();
    }

    /**
     * 泛型方法的类型转换
     */
    public static void typeConversionOfMethod() {
        var interval = new DateInterval();
        Pair<Date> pair = interval;
        pair.setFirst(new Date());
    }

}

class Pair<T> {
    private T first, second;

    public Pair() { }

    public Pair(T first) { this.first = first; }

    public Pair(T first, T second) {
        this.first = first;
        this.second = second;
    }

    /**
     * 正确的实例化类型变量
     */
    public static <T> Pair<T> makePair(Supplier<T> con) {
        return new Pair<>(con.get());
    }

    public T getFirst() { return first; }

    public void setFirst(T first) { this.first = first; }

    public T getSecond() { return second; }

    public void setSecond(T second) { this.second = second; }
}

/**
 * 泛型方法与多态性的设计
 */
class DateInterval extends Pair<Date> {
    @Override
    public void setFirst(Date first) {
        super.setFirst(first);
    }
}
